﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using CADs;
using System.ComponentModel;
using ModeloGaleriaNET;
using AvalonDock;
using System.Data.Objects.DataClasses;
using SeguridadGaleria;

namespace GaleriaNET
{
    /// <summary>
    /// Lógica de interacción para ucSubastaData.xaml
    /// </summary>
    public partial class ucSubastaData : UserControl
    {
        private string[] permisos = new string[] { TiposRoles.CREAR_SUBASTA};
        private readonly string title = "Creación de nueva subasta";
        private ObraCAD obraCAD;
        private BackgroundWorker workerObra;
        private bool success;
        private Obra obra;
        private int? idObra;
        private BackgroundWorker workerTematica, workerPermisos;
        private int originalObra;
        private double? originalPrecioPartida;
        private DateTime originalFecha;
        private int originalNegociado;
        private dynamic tematicas;
        private Brush brushNormal;
        private bool loaded;
        private SubastaCAD sCAD;
        private Dictionary<string, bool> permisosDatos;
        private IAuditoria auditoria;

        public ucSubastaData(Subasta s = null)
        {
            InitializeComponent();
            obraCAD = new ObraCAD();
            obra = null;
            workerObra = new BackgroundWorker();
            workerObra.DoWork += workerObra_DoWork;
            workerObra.RunWorkerCompleted += workerObra_RunWorkerCompleted;
            workerTematica = new BackgroundWorker();
            workerTematica.DoWork += workerTematica_DoWork;
            workerTematica.RunWorkerCompleted += workerTematica_RunWorkerCompleted;
            workerPermisos = new BackgroundWorker();
            workerPermisos.DoWork += workerPermisos_DoWork;
            workerPermisos.RunWorkerCompleted += workerPermisos_RunWorkerCompleted;
            brushNormal = cbObra.BorderBrush;
            loaded = false;
            auditoria = new AuditoriaBD();
        }

        public string Title
        {
            get { return title; }
        }

        public SubastaCAD SubastaCAD
        {
            get { return sCAD == null ? new SubastaCAD() : sCAD; }
            set { sCAD = value; }
        }

        private void workerPermisos_DoWork(object sender, DoWorkEventArgs e)
        {
            bool? value;
            string usuario;

            permisosDatos = new Dictionary<string, bool>();
            usuario = Convert.ToString(Utilities.FindUsuarioData(typeof(UserWindow), this, "Name"));
            foreach (string s in permisos)
            {
                value = ManejadorRoles.Instance.CanUse(s, usuario);      
                if (value != null)
                    permisosDatos.Add(s, value.Value);
            }
        }

        private void workerPermisos_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            bool value2;

            if (!(permisosDatos != null && permisosDatos.Count == permisos.Length))
            {
                Xceed.Wpf.Toolkit.MessageBox.Show("No se han podido obtener los permisos", "Error",
                    MessageBoxButton.OK, MessageBoxImage.Error);
                btCrear.IsEnabled = cbObra.IsEnabled = clbTematica.IsEnabled = dudPrecioPartida.IsEnabled =
                    dtpFechaInicio.IsEnabled = dtpFechaFin.IsEnabled = cbNegociado.IsEnabled = cbMaximoPujas.IsEnabled =
                    iudMaxPujas.IsEnabled = false;
            }
            else
            {
                permisosDatos.TryGetValue(TiposRoles.CREAR_SUBASTA, out value2);
                
                if (!value2)
                {
                    btCrear.IsEnabled = cbObra.IsEnabled = clbTematica.IsEnabled = dudPrecioPartida.IsEnabled =
                    dtpFechaInicio.IsEnabled = dtpFechaFin.IsEnabled = cbNegociado.IsEnabled = cbMaximoPujas.IsEnabled =
                    iudMaxPujas.IsEnabled = false;
                }
            }
            _busyIndicator.IsBusy = false;
        }

        private void workerObra_DoWork(object sender, DoWorkEventArgs e)
        {
            obra = obraCAD.GetObraById(idObra);
            success = obra != null;
        }

        private void workerTematica_DoWork(object sender, DoWorkEventArgs e)
        {
            tematicas = new TematicaCAD().GetTematicaIdNombre();
        }

        private void workerObra_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            idObra = null;
            if (success)
            {
                tbAnyoObra.Text = obra.AnyoFormato;
                tbAutorObra.Text = obra.Autor;
                tbEstadoObra.Text = procesarEstadoConservacion();
            }
        }

        private void workerTematica_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (tematicas != null)
            {
                clbTematica.ItemsSource = tematicas;
                clbTematica.DisplayMemberPath = "Nombre";
                clbTematica.SelectedMemberPath = "Id";
                clbTematica.ValueMemberPath = "Id";
                tematicas = null;
            }
        }

        private string procesarEstadoConservacion()
        {
            switch (obra.EstadoConservacion)
            {
                case "original":
                    return "Original";
                case "deteriorado":
                    return "Deteriorado";
                case "restaurado":
                    return "Restaurado";
                default:
                    return string.Empty;
            }
        }

        private void cbObra_GotFocus(object sender, RoutedEventArgs e)
        {
            dtpFechaFin_GotFocus(sender, e);
            if (cbObra.ItemsSource == null)
            {
                cbObra.ItemsSource = obraCAD.GetObrasIdNombreAutorNoSubastadas();
                cbObra.SelectedValuePath = "Id";
                cbObra.DisplayMemberPath = "NombreAutor";
                cbObra.SelectedIndex = -1;
            }
        }

        private void cbObra_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (cbObra.SelectedIndex == -1)
                tbAnyoObra.Text = tbAutorObra.Text = tbEstadoObra.Text = string.Empty;
            else
            {
                if (!workerObra.IsBusy)
                {
                    idObra = Convert.ToInt32(cbObra.SelectedValue);
                    success = false;
                    workerObra.RunWorkerAsync();
                }
            }
        }

        private void cbMaximoPujas_Checked(object sender, RoutedEventArgs e)
        {
            dtpFechaFin_GotFocus(sender, e);
            iudMaxPujas.IsEnabled = true;
            iudMaxPujas.Value = 1;
        }

        private void cbMaximoPujas_Unchecked(object sender, RoutedEventArgs e)
        {
            dtpFechaFin_GotFocus(sender, e);
            iudMaxPujas.IsEnabled = false;
            iudMaxPujas.Value = null;
        }

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            DateTime fecha;

            if (!loaded)
            {
                fecha = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, DateTime.Now.Hour + 1, 0, 0);
                dtpFechaFin.FormatString = "dd MMMM yyyy, HH:mm:ss";
                dtpFechaInicio.FormatString = "dd MMMM yyyy, HH:mm:ss";
                dtpFechaFin.Value = originalFecha = fecha; 
                dtpFechaInicio.Value = fecha;
                originalObra = -1;
                originalPrecioPartida = null;
                originalNegociado = -1;
                if (!workerTematica.IsBusy)
                    workerTematica.RunWorkerAsync();
                if (!workerPermisos.IsBusy)
                {
                    _busyIndicator.IsBusy = true;
                    workerPermisos.RunWorkerAsync();
                }
                loaded = true;
            }
        }

        private void btCancelar_Click(object sender, RoutedEventArgs e)
        {
            Close();
        }

        private void Close()
        {
            ((DocumentContent)this.Parent).Close();
        }

        public void AddEventHandler()
        {
            ((DocumentContent)this.Parent).Closing += ClosingDocument;
        }

        private void ClosingDocument(object sender, CancelEventArgs e)
        {
            if (!success)
            {
                if (HasChanges())
                {
                    if (Xceed.Wpf.Toolkit.MessageBox.Show("¿Desea salir sin aplicar los cambios?", "Salir",
                        MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.No)
                        e.Cancel = true;
                }
            }
        }

        private bool HasChanges()
        {
            if ((cbObra.ItemsSource != null && cbObra.SelectedIndex != originalObra) ||
                dudPrecioPartida.Value != originalPrecioPartida || originalFecha != dtpFechaFin.Value ||
                originalNegociado != cbNegociado.SelectedIndex || clbTematica.SelectedItems.Count > 0)
                return true;
            return false;
        }

        private bool AreCamposCorrectos()
        {
            bool salida = true;
            ToolTip t;

            if ((cbObra.ItemsSource == null || cbObra.SelectedIndex == -1) || dtpFechaInicio.Value == null ||
                clbTematica.SelectedItems.Count == 0 || dudPrecioPartida.Value == null ||
                dtpFechaFin.Value == null || cbNegociado.SelectedIndex == -1 ||
                (cbMaximoPujas.IsChecked == true && iudMaxPujas.Value == null))
            {
                if (cbObra.ItemsSource == null || cbObra.SelectedIndex == -1)
                {
                    t = new ToolTip();
                    t.Content = "Este campo no puede estar vacío";
                    cbObra.BorderBrush = new SolidColorBrush(Colors.Red);
                    cbObra.ToolTip = t;
                }

                if (clbTematica.SelectedItems.Count == 0)
                {
                    t = new ToolTip();
                    t.Content = "Debes elegir al menos una temática";
                    clbTematica.BorderBrush = new SolidColorBrush(Colors.Red);
                    clbTematica.ToolTip = t;
                    salida = false;
                }

                if (dudPrecioPartida.Value == null)
                {
                    t = new ToolTip();
                    t.Content = "Este campo no puede estar vacío";
                    dudPrecioPartida.BorderBrush = new SolidColorBrush(Colors.Red);
                    dudPrecioPartida.ToolTip = t;
                    salida = false;
                }

                if (dtpFechaFin.Value == null)
                {
                    t = new ToolTip();
                    t.Content = "Este campo no puede estar vacío";
                    dtpFechaFin.BorderBrush = new SolidColorBrush(Colors.Red);
                    dtpFechaFin.ToolTip = t;
                    salida = false;
                }

                if (dtpFechaInicio.Value == null)
                {
                    t = new ToolTip();
                    t.Content = "Este campo no puede estar vacío";
                    dtpFechaInicio.BorderBrush = new SolidColorBrush(Colors.Red);
                    dtpFechaInicio.ToolTip = t;
                    salida = false;
                }

                if (cbNegociado.SelectedIndex == -1)
                {
                    t = new ToolTip();
                    t.Content = "Este campo no puede estar vacío";
                    cbNegociado.BorderBrush = new SolidColorBrush(Colors.Red);
                    cbNegociado.ToolTip = t;
                    salida = false;
                }

                if (cbMaximoPujas.IsChecked == true && iudMaxPujas.Value == null)
                {
                    t = new ToolTip();
                    t.Content = "Este campo no puede estar vacío";
                    iudMaxPujas.BorderBrush = new SolidColorBrush(Colors.Red);
                    iudMaxPujas.ToolTip = t;
                    salida = false;
                }
            }
            else
            {
                // Campos completos, comprobación de la validez de los datos
                if (dtpFechaInicio.Value.Value >= dtpFechaFin.Value.Value)
                {
                    t = new ToolTip();
                    t.Content = "La fecha de activación de la subasta debe ser menor que la fecha de finalización";
                    dtpFechaInicio.Background = dtpFechaFin.Background = new SolidColorBrush(Colors.Salmon);
                    dtpFechaInicio.ToolTip = dtpFechaFin.ToolTip = t;
                    salida = false;
                }
                else
                {
                    if (dtpFechaInicio.Value.Value <= DateTime.Now.AddMinutes(2))
                    {
                        t = new ToolTip();
                        t.Content = "La fecha de inicio de la subasta debe ser dos minutos posterior a la fecha actual";
                        dtpFechaInicio.Background = new SolidColorBrush(Colors.Salmon);
                        dtpFechaFin.ToolTip = t;
                        salida = false;
                    }

                    if (dtpFechaFin.Value.Value <= DateTime.Now.AddMinutes(6))
                    {
                        t = new ToolTip();
                        t.Content = "La fecha de finalización de la subasta debe ser seis minutos posterior a la fecha actual";
                        dtpFechaFin.Background = new SolidColorBrush(Colors.Salmon);
                        dtpFechaFin.ToolTip = t;
                        salida = false;
                    }
                }
            }

            return salida;
        }

        private void dtpFechaFin_GotFocus(object sender, RoutedEventArgs e)
        {
            cbObra.BorderBrush = clbTematica.BorderBrush = dudPrecioPartida.BorderBrush =
            cbNegociado.BorderBrush = iudMaxPujas.BorderBrush = brushNormal;
            cbObra.ToolTip = clbTematica.ToolTip = dudPrecioPartida.ToolTip = dtpFechaInicio.ToolTip =
            dtpFechaFin.ToolTip = cbNegociado.ToolTip = iudMaxPujas.ToolTip = null;
            dtpFechaFin.Background = dtpFechaInicio.Background = new SolidColorBrush(Colors.White);
        }

        private void btCrear_Click(object sender, RoutedEventArgs e)
        {
            Subasta nueva;
            SubastaHasEstadoSubasta estado;
            ucSubastas subs;
            DocumentContent padre;
            TematicaCAD tCAD;
            int uId, zona;

            if (AreCamposCorrectos())
            {
                uId = Convert.ToInt32(Utilities.FindUsuarioData(typeof(UserWindow), this, "Id"));

                zona = Utilities.GetZonaHoraria();
                nueva = new Subasta();
                nueva.ReferenciaExterna = string.Empty;
                nueva.AnyoObra = obra.Anyo;
                nueva.AutorObra = obra.Autor;
                nueva.NombreObra = obra.Nombre;
                nueva.EstadoObra = obra.EstadoConservacion;
                nueva.TipoNegociado = cbNegociado.SelectedIndex == 0 ? "manual" : "automatico";
                nueva.PrecioPartida = (double)dudPrecioPartida.Value;
                nueva.FechaLimite = TimeZoneInfo.ConvertTime(dtpFechaFin.Value.Value, TimeZoneInfo.Utc);
                nueva.FechaInicio = TimeZoneInfo.ConvertTime(dtpFechaInicio.Value.Value, TimeZoneInfo.Utc);
                nueva.ZonaHorariaInicio = zona;
                nueva.ZonaInicioFin = zona;

                if (cbMaximoPujas.IsChecked == true)
                    nueva.MaximoPujasPostor = (int)iudMaxPujas.Value;
                else
                    nueva.MaximoPujasPostor = Int32.MaxValue;

                // Temáticas
                tCAD = new TematicaCAD();
                foreach (object item in clbTematica.SelectedItems)
                    nueva.Tematicas.Add(tCAD.GetTematicaById(Convert.ToInt32(item.GetType().GetProperty("Id").GetValue(item, null))));

                // Establecer estado como creada
                estado = new SubastaHasEstadoSubasta();
                estado.FechaInicio = DateTime.UtcNow;
                estado.zonaFechaInicio = zona;
                estado.zonaFechaFin = zona;
                estado.EstadosSubastaReference.EntityKey = new EstadoSubastaCAD().GetEstadoCreada().EntityKey;
                nueva.SubastaHasEstadosSubasta.Add(estado);

                // Establecer clientePropietarioObra
                nueva.ClientesPropietariosObras = obra.ClientePropietarioObraActual;

                // Insertar subasta en la base de datos
                if (sCAD.GuardarNuevaSubastaPropia(nueva))
                {
                    auditoria.Mensaje(new object[] { nueva.Id }, TiposAuditoria.Ordinal(TiposAuditoria.TIPO_AUDITORIA.CREAR_SUBASTA_LOCAL), uId);
                    System.Threading.Thread.Sleep(1000);
                    // Xceed.Wpf.Toolkit.MessageBox.Show("Subasta creada con éxito", "Subasta creada",
                    //       MessageBoxButton.OK, MessageBoxImage.Information);
                    if ((padre = (DocumentContent)(FindDocumentContent(typeof(ucSubastas)))) != null)
                    {
                        subs = (ucSubastas)(padre.Content);
                        subs.ActualizarDataGrid();
                        Close();
                    }
                }
                else
                {
                    auditoria.Mensaje(new object[] { nueva.Id }, TiposAuditoria.Ordinal(TiposAuditoria.TIPO_AUDITORIA.ERROR_CREAR_SUBASTA_LOCAL), uId);
                    System.Threading.Thread.Sleep(1000);
                    Xceed.Wpf.Toolkit.MessageBox.Show("No ha sido posible realizar la creación de la subasta",
                        "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }
            }
        }

        private DocumentContent FindDocumentContent(Type t)
        {
            DockingManager manager;

            manager = ((DocumentContent)this.Parent).Manager;
            // Buscamos si hay abierta una instancia del documento a abrir
            foreach (AvalonDock.DocumentContent doc in manager.Documents)
            {
                if (doc.Content.GetType() == t)
                    return doc;
            }
            return null;
        }
    }
}
